/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
/* tcpok.c - tcpok */

#include "tcp.h"
#include "tcb.h"
#include "tcpfms.h"

/*------------------------------------------------------------------------
 *  tcpok -  determina se o segmento recebido eh aceitavel
 *------------------------------------------------------------------------
 */
//verificar
int tcpok(struct tcb *ptcb, struct udp *pudp){

    //struct	ip	*pip = (struct ip *)pep->ep_data;
    struct	tcp	*ptcp = (struct tcp*)(pudp->udp_data);
    int  seglen;
    int  rwindow;
    tcpseq	wlast, slast;
    int		rv; // bool

    if (ptcb->tcb_state < TCPS_SYNRCVD)
        return 1;
    //seglen = pip->ip_len - IP_HLEN(pip) - TCP_HLEN(ptcp);
    seglen = sizeof(*ptcp) - TCP_HLEN(ptcp);

    // adiciona SYN e FIN
    if (ptcp->tcp_code & TCPF_SYN)
        ++seglen;
    if (ptcp->tcp_code & TCPF_FIN)
        ++seglen;
    rwindow = ptcb->tcb_rbsize - ptcb->tcb_rbcount;
    if (rwindow == 0 && seglen == 0)
        return ptcp->tcp_seq == ptcb->tcb_rnext;
    wlast = ptcb->tcb_rnext + rwindow - 1;
    rv = (ptcp->tcp_seq - ptcb->tcb_rnext) >= 0 &&
        (ptcp->tcp_seq - wlast) <= 0;
    if (seglen == 0)
        return rv;
    slast = ptcp->tcp_seq + seglen - 1;
    rv |= (slast - ptcb->tcb_rnext) >= 0 && (slast - wlast) <= 0;

    // If no window, strip data but keep ACK, RST and URG
    if (rwindow == 0)
        // pip->ip_len = IP_HLEN(pip) + TCP_HLEN(ptcp);
    	pudp->udp_len = TCP_HLEN(ptcp);
    return rv;
}
